package com.levi.stream;

import com.levi.lambda.Student;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author shentong
 * @date 2022/1/12 7:20 PM
 * @description  Stream收集器
 */
public class DemoCollect {
    public static void main(String[] args) {
        List<Student> students = new ArrayList<Student>(){{
            add(new Student(1,"zhangsan","man",20,true,90));
            add(new Student(2,"zhangsan","man",20,true,80));
            add(new Student(3,"lisi","woman",20,false,30));
            add(new Student(4,"lisi","woman",20,false,40));
            add(new Student(5,"wangwu","man",25,true,95));
            add(new Student(6,"wangwu","man",25,true,90));
            add(new Student(7,"zhaoliu","woman",25,false,50));
            add(new Student(8,"zhaoliu","woman",25,false,20));
        }};
        //jdk8之前的写法   通过性别进行分布，返回map
        Map<String,List<Student>> map = new HashMap<>();
        for (Student student : students) {
            String sex = student.getSex();
            if (map.get(sex) == null) {
                List<Student> tempstudents = new ArrayList<>();
                tempstudents.add(student);
                map.put(sex, tempstudents);
            }else{
                map.get(sex).add(student);
            }
        }
        System.out.println("jdk8之前写法："+map);
        //jdk8 Stream流式计算
        Map<String, List<Student>> collect = students.stream().collect(Collectors.groupingBy(Student::getSex));
        System.out.println("jdk8 Stream流式计算写法: "+collect);
        //统计集合中元素总数
        long count = students.stream().collect(Collectors.counting());
        long count1 = students.stream().count();
        //获取集合中学生年龄最大值和最小值
        Optional<Student> collectMax = students.stream().collect(Collectors.maxBy(Comparator.comparing(Student::getAge)));
        collectMax.ifPresent(System.out::println);
        Optional<Student> collectMin = students.stream().collect(Collectors.minBy(Comparator.comparing(Student::getAge)));
        collectMin.ifPresent(System.out::println);

        Optional<Student> max = students.stream().max(Comparator.comparing(Student::getAge));
        max.ifPresent(System.out::println);
        Optional<Student> min = students.stream().min(Comparator.comparing(Student::getAge));
        min.ifPresent(System.out::println);

        //获取所有学生的年龄之和
        Integer sum1 = students.stream().collect(Collectors.summingInt(Student::getAge));
        int sum2 = students.stream().mapToInt(Student::getAge).sum();
        //获取所有学生年龄的平均值
        Double avg1 = students.stream().collect(Collectors.averagingDouble(Student::getAge));
        OptionalDouble average = students.stream().mapToDouble(Student::getAge).average();
        average.ifPresent(System.out::println);
        //复杂返回结果 包含 和、平均值、最大值、最小值,元素总数
        IntSummaryStatistics all = students.stream().collect(Collectors.summarizingInt(Student::getAge));
        double avg = all.getAverage();
        int max1 = all.getMax();
        int min1 = all.getMin();
        long count2 = all.getCount();
        long sum = all.getSum();
        //根据对象集合中某个字段拼接字符串
        String join = students.stream().map(Student::getName).collect(Collectors.joining(","));
        System.out.println("拼接后的结果是： "+join);
        //多级分组
        //根据年龄进行分组，获取并汇总不同年龄的人数
        Map<Integer, Long> collect1 = students.stream().collect(Collectors.groupingBy(Student::getAge, Collectors.counting()));
        System.out.println(collect1);
        //先根据年龄进行分组，然后根据是否及格进行分组，最后根据结果汇总人数
        Map<Integer, Map<Boolean, Long>> collect2 = students.stream().collect(Collectors.groupingBy(Student::getAge, Collectors.groupingBy(Student::getPass, Collectors.counting())));
        System.out.println(collect2);
        //根据年龄分组，然后根据是否及格进行分组，最后根据结果获取每组中分数最高的学生
        //collectingAndThen  收集之后再追加一个方法
        Map<Integer, Map<Boolean, Student>> collect3 = students.stream().collect(Collectors.groupingBy(Student::getAge,
                Collectors.groupingBy(Student::getPass,
                        Collectors.collectingAndThen(Collectors.maxBy(Comparator.comparing(Student::getScore)),
                                Optional::get))));
        System.out.println("-----------");
        System.out.println(collect3);
    }
}
